package com.wl.application.interceptor;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.wl.application.common.all.Const;
import com.wl.application.context.LoginLocalThread;
import com.wl.application.common.all.ResultEnum;
import com.wl.application.common.untils.TokenUtil;
import com.wl.application.common.childException.TokenException;
import com.wl.application.common.childException.UserNoLoginException;
import com.wl.application.controller.UserController;
import com.wl.application.entity.LoginUser;
import com.wl.application.entity.User;
import com.wl.application.services.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author wl
 * @version 1.0
 * @date 2022/6/16
 * @description: 登录拦截校验器
 */
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private UserController userController;

    @Autowired
    private LoginService loginService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求中的token
        String token = request.getHeader("token");
        //对token进行校验
        //1.token为空,用户未登录
        if (token == null) {
            throw new UserNoLoginException(ResultEnum.NO_LOGIN.getCode(),ResultEnum.NO_LOGIN.getMsg());
        }
        try {
            //进行token校验
            TokenUtil.checkToken(token);
        }catch (TokenExpiredException e) {
            throw  new TokenException(ResultEnum.LOGIN_TIME_OUT.getCode(), ResultEnum.LOGIN_TIME_OUT.getMsg());
        } catch (JWTVerificationException e) {
            throw new TokenException(ResultEnum.TOKEN_EXCEPTION.getCode(),ResultEnum.TOKEN_EXCEPTION.getMsg());
        }

        //2.解析token获得数据
        Map map = TokenUtil.analysisToken(token, Map.class);

        //3.在redis数据库中查询
        LoginUser loginUser=loginService.getUserByToken(map);

        //实时查询该账户是否被冻结
        User one = (User) userController.getOne(loginUser.getId()).getData();
        if(one.getUstate().equals(Const.NO_ACTIVATE)){
            throw new TokenException(ResultEnum.USER_FREEZE.getCode(),ResultEnum.USER_FREEZE.getMsg());
        }
        //3.将token存在本地线程池中
        LoginLocalThread.setLocal(loginUser);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //清除用户数据
        LoginLocalThread.remove();;
    }
}
